#ifndef __FUNC_H__
#define __FUNC_H__
#include <my_header.h>
/* Usage: 服务端业务功能函数声明 */
//缓冲区大小
#define BUF_SIZE 1024
//外部维护的系统级工作目录
#define ROOTDIR "/home/zyn/user_space"
//100 MB
#define HUNDRED_MEGABYTE 104857600
// 定义进度条宽度
#define PROGRESS_BAR_WIDTH 25

typedef enum{
    TAGREGISTER = 1,
    TAGLOGIN,
    TAGCANCEL,
    TAGCD,
    TAGLS,
    TAGREMOVE,
    TAGPWD,
    TAGMKDIR,
    TAGRMDIR,
    TAGGETS,
    TAGPUTS,
    TAG_RESPONSEREGISTER,
    TAG_RESPONSELOGIN,
    TAG_RESPONSECANCEL,
    TAG_RESPONSECD,
    TAG_RESPONSELS,
    TAG_RESPONSEREMOVE,
    TAG_RESPONSEPWD,
    TAG_RESPONSEMKDIR,
    TAG_RESPONSERMDIR,
    TAG_RESPONSEGETS,
    TAG_RESPONSEPUTS,
    TAG_ERROR,
} Tag;

//套接字类型
typedef int socket_t;
//小火车传输消息和文件
typedef struct train_s {
    int tag;
    int data_length;
    char data[BUF_SIZE];
} train_t, *ptrain_t;

typedef struct userInfo_s{
    char username[64];
    char current_path[256];
} userInfo_t;

// 客户端连接日志宏
#define RECORD_LOG_CONNECT(fd_log, fd_client) do { \
    time_t nowtime; \
    time(&nowtime); \
    char buf[128] = ""; \
    sprintf(buf, "fd_client = %d:%s\n%s\n", (fd_client), ("connect"), ctime(&nowtime)); \
    write((fd_log), buf, strlen(buf)); \
} while(0)
// 客户端命令日志宏
#define RECORD_LOG_CMD(fd_log, fd_client, pcmd) do { \
    time_t nowtime; \
    time(&nowtime); \
    char buf[128] = ""; \
    sprintf(buf, "fd_client = %d:", (fd_client)); \
    for (int i = 0; i < (pcmd)->argc; i++) { \
        strcat(buf, (pcmd)->cmd[i]); \
        strcat(buf, " "); \
    } \
    strcat(buf, "\n"); \
    strcat(buf, ctime(&nowtime)); \
    strcat(buf, "\n"); \
    write((fd_log), buf, strlen(buf)); \
} while(0)

//发小火车
int send_train(socket_t fd_client, int tag, const char *data);

//目录操作相关函数
//显示当前虚拟工作路径
int do_pwd(socket_t fd_client, char *cur_path);
//显示当前目录下的文件信息
int do_ls(socket_t fd_client, MYSQL *mysql, char *cur_path);
//实现虚拟工作路径跳转（可以处理 ..到上一级）
int do_cd(socket_t fd_client, MYSQL *mysql, char *cur_path);
//创建目录文件（需要涉及到file表的插入操作）
int do_mkdir(socket_t fd_client, MYSQL *mysql, char *cur_path);
//删除目录文件（需要涉及到file表的更新操作--is_deleted）
int do_rmdir(socket_t fd_client, MYSQL *mysql, char *cur_path);
//删除文件，仅支持单个文件名（涉及到file表的更新操作--is_deleted）                                                                              
int do_remove(socket_t fd_client, MYSQL *mysql, char *cur_path);

//文件上传下载相关函数
//发送小火车函数
int send_train(socket_t fd_client, int tag, const char *data);
//删除文件，仅支持单个文件名
int do_remove(socket_t fd_client, MYSQL *mysql, char *cur_path);
//处理客户端上传文件
int do_puts(socket_t fd_client, MYSQL *mysql, char *cur_path);
//处理客户端的文件下载请求
int do_gets(socket_t fd_client, MYSQL *mysql, char *cur_path);
// 获取文件大小函数
int get_filesize(char *filename);
//接收文件
int recv_file_train(socket_t fd_client, MYSQL *mysql, const char* file_hash, const char *transferred_filename, char *real_filename, off_t file_size, off_t transferred_file_size);
//用普通方式传输文件 file_size < 100M
int send_file_train(int fd_socket, char *filename);
//用零拷贝方式传输文件 file_size > 100M
int send_file_sendfile(int fd_socket, char *filename, off_t filesize);
#endif
